#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <signal.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>

int sockfd, connfd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;

void sig_urg(int signo) {
	int n;
	char buff[10] = {0};

	n = recv(connfd, buff, sizeof(buff), MSG_OOB);
	buff[n] = '\0';
	printf("oob: %d %s\n", n, buff);
}

int main(int argc, char* argv[]) {
	int len = sizeof(server_addr);

	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	server_addr.sin_port = htons(4567);

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	bind(sockfd, (struct sockaddr*)&server_addr, len);
	listen(sockfd,20);
	
/*
	connfd = accept(sockfd, (struct sockaddr*)&client_addr, &len);

	signal(SIGURG, sig_urg);
	fcntl(connfd, F_SETOWN, getpid());
	while (1) {		
		char buf[100] = {0};
		if (read(connfd, buf, 100) < 0)
			break;	

		printf("svr_read: %s\n", buf);
	}
*/

/*
	fd_set rset, xset;
	int justreadoob = 0;
	FD_ZERO(&rset);
	FD_ZERO(&xset);

	connfd = accept(sockfd, (struct sockaddr*)&client_addr, &len);

	for (; ;) {
		FD_SET(connfd, &rset);
		if (justreadoob == 0)
			FD_SET(connfd, &xset);
		
		select(connfd+1, &rset, NULL, &xset, NULL);
		if (FD_ISSET(connfd, &xset)) {
			char buf[100] = {0};
			if (recv(connfd, buf, 100, MSG_OOB) < 0)
				break;	

			justreadoob = 1;
			printf("oob_read: %s\n", buf);
		}

		if (FD_ISSET(connfd, &rset)) {
			char buf[100] = {0};
			if (read(connfd, buf, 100) < 0)
				break;	

			justreadoob = 0;
			printf("svr_read: %s\n", buf);
		}
	}
*/
	int on = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));
	connfd = accept(sockfd, (struct sockaddr*)&client_addr, &len);

	sleep(2);
	for(; ;) {
		if (sockatmark(connfd))
			printf("at oob\n");

		char buf[100] = {0};
		if (read(connfd, buf, 100) < 0)
			break;	

		printf("svr_read: %s\n", buf);
	}

	close(sockfd);
	return 0;
}
